home *** CD-ROM | disk | FTP | other *** search
/ Gamers Delight 2 / Gamers Delight 2.iso / Aminet / game / role / Ang261Lib.lha / src / unix.c < prev    next >
C/C++ Source or Header  |  1994-10-22  |  8KB  |  357 lines

  1. /*
  2.  * unix.c: UNIX dependent code.                    -CJS- 
  3.  *
  4.  * Copyright (c) 1989 James E. Wilson, Christopher J. Stuart 
  5.  *
  6.  * This software may be copied and distributed for educational, research, and
  7.  * not for profit purposes provided that this copyright and statement are
  8.  * included in all such copies. 
  9.  */
  10.  
  11. #if defined(unix) || defined(__MINT__) || defined(AMIGA)
  12.  
  13. /* defines NULL */
  14. #include <stdio.h>
  15. /* defines CTRL */
  16. #include <sys/ioctl.h>
  17.  
  18. /* defines TRUE and FALSE */
  19. #ifdef linux
  20. #include <ncurses.h>
  21. #else
  22. #include <curses.h>
  23. #endif
  24.  
  25. #include <pwd.h>
  26. #include "constant.h"
  27. #include "config.h"
  28. #include "types.h"
  29. #include "externs.h"
  30.  
  31. #if defined(SYS_V) && defined(lint)
  32. /* for AIX, prevent hundreds of unnecessary lint errors, must define before
  33.  * signal.h is included 
  34.  */
  35. #define _h_IEEETRAP
  36. typedef struct {
  37.     int                 stuff;
  38. }                   fpvmach;
  39.  
  40. #endif
  41.  
  42. #include <signal.h>
  43.  
  44. #ifdef M_XENIX
  45. #include <sys/select.h>
  46. #endif
  47.  
  48. #ifndef USG
  49. #include <sys/time.h>
  50. #include <sys/resource.h>
  51. #include <sys/types.h>
  52. #include <sys/param.h>
  53. #endif
  54.  
  55. #ifdef USG
  56. #include <string.h>
  57. #ifndef __MINT__
  58. #include <termio.h>
  59. #endif
  60. #include <fcntl.h>
  61. #else
  62. #include <strings.h>
  63. #if defined(atarist) && defined(__GNUC__) && !defined(__MINT__)
  64. /* doesn't have <sys/wait.h> */
  65. #else
  66. #include <sys/wait.h>
  67. #endif
  68. #endif
  69.  
  70. /* #include <pwd.h> */
  71. #include <sys/errno.h>
  72.  
  73. struct passwd      *getpwuid();
  74. struct passwd      *getpwnam();
  75.  
  76. #if defined(SYS_V) && defined(lint)
  77. struct screen {
  78.     int                 dumb;
  79. };
  80.  
  81. #endif
  82.  
  83. /* Fooling lint. Unfortunately, c defines all the TIO constants to be long,
  84.  * and lint expects them to be int. Also, ioctl is sometimes called with just
  85.  * two arguments. The following definition keeps lint happy. It may need to
  86.  * be reset for different systems. 
  87.  */
  88. #ifdef lint
  89. #ifdef Pyramid
  90. /* Pyramid makes constants greater than 65535 into long! Gakk! -CJS- */
  91. /* ARGSUSED */
  92. /* VARARGS2 */
  93. static 
  94.     Ioctl(i, l, p) long l;
  95.     char               *p;
  96. {
  97.     return 0;
  98. }
  99.  
  100. #else
  101. /* ARGSUSED */
  102. /* VARARGS2 */
  103. static 
  104.     Ioctl(i, l, p) char *p;
  105. {
  106.     return 0;
  107. }
  108.  
  109. #endif
  110. #define ioctl        Ioctl
  111. #endif
  112.  
  113. /* Provides for a timeout on input. Does a non-blocking read, consuming the
  114.  * data if any, and then returns 1 if data was read, zero otherwise. 
  115.  *
  116.  * Porting: 
  117.  *
  118.  * In systems without the select call, but with a sleep for fractional numbers
  119.  * of seconds, one could sleep for the time and then check for input. 
  120.  *
  121.  * In systems which can only sleep for whole number of seconds, you might sleep
  122.  * by writing a lot of nulls to the terminal, and waiting for them to drain,
  123.  * or you might hack a static accumulation of times to wait. When the
  124.  * accumulation reaches a certain point, sleep for a second. There would need
  125.  * to be a way of resetting the count, with a call made for commands like run
  126.  * or rest. 
  127.  */
  128. int 
  129. check_input(microsec)
  130.     int                 microsec;
  131. {
  132. #if defined(USG) && !defined(M_XENIX)
  133.     int                 arg, result;
  134.  
  135. #else
  136.     struct timeval      tbuf;
  137.     int                 ch;
  138.  
  139. #if defined(BSD4_3) || defined(M_XENIX) || defined(linux)
  140.     fd_set              smask;
  141.  
  142. #else
  143.     int                 smask;
  144.  
  145. #endif
  146. #endif
  147.  
  148. /* Return true if a read on descriptor 1 will not block. */
  149. #if !defined(USG) || defined(M_XENIX)
  150.     tbuf.tv_sec = 0;
  151.     tbuf.tv_usec = microsec;
  152. #if defined(BSD4_3) || defined(M_XENIX) || defined(linux)
  153.     FD_ZERO(&smask);
  154.     FD_SET(fileno(stdin), &smask);
  155.     if (select(1, &smask, (fd_set *) 0, (fd_set *) 0, &tbuf) == 1)
  156. #else
  157.     smask = 1;               /* i.e. (1 << 0) */
  158.     if (select(1, &smask, (int *)0, (int *)0, &tbuf) == 1)
  159. #endif
  160.     {
  161.     ch = getch();
  162.     /* check for EOF errors here, select sometimes works even when EOF */
  163.     if (ch == -1) {
  164.         eof_flag++;
  165.         return 0;
  166.     }
  167.     return 1;
  168.     } else
  169.     return 0;
  170. #else                   /* SYS V code follows */
  171.     if (microsec != 0 && (turn & 0x7F) == 0)
  172.     (void)sleep(1);           /* mod 128, sleep one sec every 128 turns */
  173. /* Can't check for input, but can do non-blocking read, so... */
  174. /* Ugh! */
  175.     arg = 0;
  176.     arg = fcntl(0, F_GETFL, arg);
  177.     arg |= O_NDELAY;
  178.     (void)fcntl(0, F_SETFL, arg);
  179.  
  180.     result = getch();
  181.  
  182.     arg = 0;
  183.     arg = fcntl(0, F_GETFL, arg);
  184.     arg &= ~O_NDELAY;
  185.     (void)fcntl(0, F_SETFL, arg);
  186.     if (result == -1)
  187.     return 0;
  188.     else
  189.     return 1;
  190. #endif
  191. }
  192.  
  193. #if 0
  194. /*
  195.  * This is not used, however, this should be compared against shell_out in
  196.  * io.c 
  197.  */
  198.  
  199. /*
  200.  * A command for the operating system. Standard library function 'system' is
  201.  * unsafe, as it leaves various file descriptors open. This also is very
  202.  * careful with signals and interrupts, and does rudimentary job control, and
  203.  * puts the terminal back in a standard mode. 
  204.  */
  205. int 
  206. system_cmd(p)
  207.     char               *p;
  208. {
  209.     int                 pgrp, pid, i, mask;
  210.     union wait          w;
  211.     extern char        *getenv();
  212.  
  213.     mask = sigsetmask(~0);       /* No interrupts. */
  214.     restore_term();           /* Terminal in original state. */
  215. /* Are we in the control terminal group? */
  216.     if (ioctl(0, TIOCGPGRP, (char *)&pgrp) < 0 || pgrp != getpgrp(0))
  217.     pgrp = (-1);
  218.     pid = fork();
  219.     if (pid < 0) {
  220.     (void)sigsetmask(mask);
  221.     moriaterm();
  222.     return (-1);
  223.     }
  224.     if (pid == 0) {
  225.     (void)sigsetmask(0);       /* Interrupts on. */
  226.     /* Transfer control terminal. */
  227.     if (pgrp >= 0) {
  228.         i = getpid();
  229.         (void)ioctl(0, TIOCSPGRP, (char *)&i);
  230.         (void)setpgrp(i, i);
  231.     }
  232.     for (i = 2; i < 30; i++)
  233.         (void)close(i);       /* Close all but standard in and out. */
  234.     (void)dup2(1, 2);       /* Make standard error as standard out. */
  235.     if (p == 0 || *p == 0) {
  236.         p = getenv("SHELL");
  237.         if (p)
  238.         execl(p, p, 0);
  239.         execl("/bin/sh", "sh", 0);
  240.     } else
  241.         execl("/bin/sh", "sh", "-c", p, 0);
  242.     _exit(1);
  243.     }
  244. /* Wait for child termination. */
  245.     for (;;) {
  246.     i = wait3(&w, WUNTRACED, (struct rusage *) 0);
  247.     if (i == pid) {
  248.         if (WIFSTOPPED(w)) {
  249.         /* Stop outselves, if child stops. */
  250.         (void)kill(getpid(), SIGSTOP);
  251.         /* Restore the control terminal, and restart subprocess. */
  252.         if (pgrp >= 0)
  253.             (void)ioctl(0, TIOCSPGRP, (char *)&pid);
  254.         (void)killpg(pid, SIGCONT);
  255.         } else
  256.         break;
  257.     }
  258.     }
  259. /* Get the control terminal back. */
  260.     if (pgrp >= 0)
  261.     (void)ioctl(0, TIOCSPGRP, (char *)&pgrp);
  262.     (void)sigsetmask(mask);       /* Interrupts on. */
  263.     moriaterm();           /* Terminal in moria mode. */
  264.     return 0;
  265. }
  266.  
  267. #endif
  268.  
  269.  
  270. /* Find a default user name from the system. */
  271. void 
  272. user_name(buf, id)
  273.     char               *buf;
  274.     int id;
  275. {
  276.     struct passwd      *pwd;
  277.  
  278.     pwd = getpwuid(id);
  279.     (void)strcpy(buf, pwd->pw_name);
  280.     if (*buf >= 'a' && *buf <= 'z')
  281.     *buf = (*buf - 'a') + 'A';
  282. }
  283.  
  284. /* expands a tilde at the beginning of a file name to a users home directory */
  285. int 
  286. tilde(file, exp)
  287.     const char   *file;
  288.     char         *exp;
  289. {
  290.     *exp = '\0';
  291.     if (file) {
  292.     if (*file == '~') {
  293.         char                user[128];
  294.         struct passwd      *pw = NULL;
  295.         int                 i = 0;
  296.  
  297.         user[0] = '\0';
  298.         file++;
  299.         while (*file != '/' && i < sizeof(user))
  300.         user[i++] = *file++;
  301.         user[i] = '\0';
  302.         if (i == 0) {
  303.         char               *login = (char *)getlogin();
  304.  
  305.         if (login != NULL)
  306.             (void)strcpy(user, login);
  307.         else if ((pw = getpwuid(getuid())) == NULL)
  308.             return 0;
  309.         }
  310.         if (pw == NULL && (pw = getpwnam(user)) == NULL)
  311.         return 0;
  312.         (void)strcpy(exp, pw->pw_dir);
  313.     }
  314.     (void)strcat(exp, file);
  315.     return 1;
  316.     }
  317.     return 0;
  318. }
  319.  
  320. /*
  321.  * open a file just as does fopen, but allow a leading ~ to specify a home
  322.  * directory 
  323.  */
  324. FILE               *
  325. my_tfopen(file, mode)
  326.     const char               *file;
  327.     const char               *mode;
  328. {
  329.     char                buf[1024];
  330.     extern int          errno;
  331.  
  332.     if (tilde(file, buf))
  333.     return (fopen(buf, mode));
  334.     errno = ENOENT;
  335.     return NULL;
  336. }
  337.  
  338. /*
  339.  * open a file just as does open, but expand a leading ~ into a home
  340.  * directory name 
  341.  */
  342. int 
  343. my_topen(file, flags, mode)
  344.     const char               *file;
  345.     int                 flags, mode;
  346. {
  347.     char                buf[1024];
  348.     extern int          errno;
  349.  
  350.     if (tilde(file, buf))
  351.     return (open(buf, flags, mode));
  352.     errno = ENOENT;
  353.     return -1;
  354. }
  355.  
  356. #endif
  357.